Linux Socket C語言網路程式設計:Pthread Socket [code from GitHub, for study]
pthreat socket
three file in one directory
config.h
server.c
client.c
config.h
/*
* config.h 包含該tcp/ip套接字程式設計所需要的基本標頭檔案,與server.c client.c位於同
一目錄下
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <pthread.h>
const int MAX_LINE = 2048;
const int PORT = 6001;
const int BACKLOG = 10;
const int LISTENQ = 6666;
const int MAX_CONNECT = 20;
server.c
/*
* 伺服器端程式碼實現
*/
#include "config.h"
/*處理接收客戶端訊息函式*/
void *recv_message(void *fd)
{
int sockfd = *(int *)fd;
while(1)
{
char buf[MAX_LINE];
memset(buf , 0 , MAX_LINE);
int n;
if((n = recv(sockfd , buf , MAX_LINE , 0)) == -1)
{
perror("recv error.\n");
exit(1);
}//if
buf[n] = '\0';
//若收到的是exit字元,則代表退出通訊
if(strcmp(buf , "byebye.") == 0)
{
printf("Client closed.\n");
close(sockfd);
exit(1);
}//if
printf("\nClient: %s\n", buf);
}//while
}
int main()
{
//宣告套接字
int listenfd , connfd;
socklen_t clilen;
//宣告執行緒ID
pthread_t recv_tid , send_tid;
//定義地址結構
struct sockaddr_in servaddr , cliaddr;
/*(1) 建立套接字*/
if((listenfd = socket(AF_INET , SOCK_STREAM , 0)) == -1)
{
perror("socket error.\n");
exit(1);
}//if
/*(2) 初始化地址結構*/
bzero(&servaddr , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(PORT);
/*(3) 繫結套接字和埠*/
if(bind(listenfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) < 0)
{
perror("bind error.\n");
exit(1);
}//if
/*(4) 監聽*/
if(listen(listenfd , LISTENQ) < 0)
{
perror("listen error.\n");
exit(1);
}//if
/*(5) 接受客戶請求,並建立執行緒處理*/
clilen = sizeof(cliaddr);
if((connfd = accept(listenfd , (struct sockaddr *)&cliaddr , &clilen)) < 0)
{
perror("accept error.\n");
exit(1);
}//if
printf("server: got connection from %s\n", inet_ntoa(cliaddr.sin_addr));
/*建立子執行緒處理該客戶連結接收訊息*/
if(pthread_create(&recv_tid , NULL , recv_message, &connfd) == -1)
{
perror("pthread create error.\n");
exit(1);
}//if
/*處理伺服器傳送訊息*/
char msg[MAX_LINE];
memset(msg , 0 , MAX_LINE);
while(fgets(msg , MAX_LINE , stdin) != NULL)
{
if(strcmp(msg , "exit\n") == 0)
{
printf("byebye.\n");
memset(msg , 0 , MAX_LINE);
strcpy(msg , "byebye.");
send(connfd , msg , strlen(msg) , 0);
close(connfd);
exit(0);
}//if
if(send(connfd , msg , strlen(msg) , 0) == -1)
{
perror("send error.\n");
exit(1);
}//if
}//while
}
client.c
/*
* 客戶端程式碼
*/
#include "config.h"
/*處理接收伺服器訊息函式*/
void *recv_message(void *fd)
{
int sockfd = *(int *)fd;
while(1)
{
char buf[MAX_LINE];
memset(buf , 0 , MAX_LINE);
int n;
if((n = recv(sockfd , buf , MAX_LINE , 0)) == -1)
{
perror("recv error.\n");
exit(1);
}//if
buf[n] = '\0';
//若收到的是exit字元,則代表退出通訊
if(strcmp(buf , "byebye.") == 0)
{
printf("Server is closed.\n");
close(sockfd);
exit(0);
}//if
printf("\nServer: %s\n", buf);
}//while
}
int main(int argc , char **argv)
{
/*宣告套接字和連結伺服器地址*/
int sockfd;
pthread_t recv_tid , send_tid;
struct sockaddr_in servaddr;
/*判斷是否為合法輸入*/
if(argc != 2)
{
perror("usage:tcpcli <IPaddress>");
exit(1);
}//if
/*(1) 建立套接字*/
if((sockfd = socket(AF_INET , SOCK_STREAM , 0)) == -1)
{
perror("socket error");
exit(1);
}//if
/*(2) 設定連結伺服器地址結構*/
bzero(&servaddr , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
if(inet_pton(AF_INET , argv[1] , &servaddr.sin_addr) < 0)
{
printf("inet_pton error for %s\n",argv[1]);
exit(1);
}//if
/*(3) 傳送連結伺服器請求*/
if( connect(sockfd , (struct sockaddr *)&servaddr , sizeof(servaddr)) < 0)
{
perror("connect error");
exit(1);
}//if
/*建立子執行緒處理該客戶連結接收訊息*/
if(pthread_create(&recv_tid , NULL , recv_message, &sockfd) == -1)
{
perror("pthread create error.\n");
exit(1);
}//if
/*處理客戶端傳送訊息*/
char msg[MAX_LINE];
memset(msg , 0 , MAX_LINE);
while(fgets(msg , MAX_LINE , stdin) != NULL)
{
if(strcmp(msg , "exit\n") == 0)
{
printf("byebye.\n");
memset(msg , 0 , MAX_LINE);
strcpy(msg , "byebye.");
send(sockfd , msg , strlen(msg) , 0);
close(sockfd);
exit(0);
}//if
if(send(sockfd , msg , strlen(msg) , 0) == -1)
{
perror("send error.\n");
exit(1);
}//if
}//while
}
complied
$ gcc server.c -o server -pthread
$ gcc client.c -o client -pthread
run
$ ./server &
$ ./client 127.0.0.1
相關文章
- Linux Socket C語言網路程式設計:Poll Socket [code from GitHub, for study]LinuxC語言程式設計Github
- Linux Socket C語言網路程式設計:Epoll Socket [code from GitHub, for study]LinuxC語言程式設計Github
- Linux Socket C語言網路程式設計:TCP SocketLinuxC語言程式設計TCP
- Linux Socket C語言網路程式設計:UDP SocketLinuxC語言程式設計UDP
- Linux Socket C語言網路程式設計:Select SocketLinuxC語言程式設計
- Go 語言使用.NET 包實現 Socket 網路程式設計Go程式設計
- socket網路程式設計程式設計
- 網路程式設計-socket程式設計
- 【Linux網路程式設計】Socket Api函式Linux程式設計API函式
- python網路-Socket之TCP程式設計(26)PythonTCP程式設計
- 網路程式設計之socket程式設計
- python:socket網路程式設計Python程式設計
- SOCKET程式設計程式設計
- 網路程式設計-Socket通訊程式設計
- 【網路程式設計】socket詳解程式設計
- HUST-計算機網路實驗-socket程式設計計算機網路程式設計
- Java Socket程式設計Java程式設計
- socket程式設計(1)程式設計
- Socket程式設計模型程式設計模型
- Python socket程式設計Python程式設計
- UDP協議網路Socket程式設計(java實現C/S通訊案例)UDP協議程式設計Java
- Java 網路程式設計 —— Socket 詳解Java程式設計
- go socket、http網路程式設計demoGoHTTP程式設計
- Socket程式設計基礎程式設計
- socket程式設計實戰程式設計
- Java:基於TCP協議網路socket程式設計(實現C/S通訊)JavaTCP協議程式設計
- java多執行緒實現TCP網路Socket程式設計(C/S通訊)Java執行緒TCP程式設計
- Liunx C 程式設計之多執行緒與Socket程式設計執行緒
- linux非阻塞式socket程式設計之select()用法Linux程式設計
- python資源庫——socket網路程式設計Python程式設計
- socket程式設計實現tcp伺服器_C/C++程式設計TCP伺服器C++
- 【socket程式設計基礎模板】程式設計
- select函式socket程式設計函式程式設計
- golang中的socket程式設計Golang程式設計
- 玩轉 PHP 網路程式設計全套之 socket stream 程式設計PHP程式設計
- 網路協議之:socket協議詳解之Socket和Stream Socket協議
- C語言透過socket實現TCP客戶端C語言TCP客戶端
- PHP回顧之socket程式設計PHP程式設計