TCP 和 UDP 服务器的创建
tcp_udp_server.c
/* tcp_udp_server.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int udpsockfd = 0;
int tcpsockfd = 0;
int tcpsock_client_fd = 0;
int udpport = 0;
int tcpport = 0;
struct sockaddr_in udp_addr;
struct sockaddr_in tcp_addr;
#define BUFF_LEN 1024
char tcp_recvbuff[BUFF_LEN];
pthread_mutex_t pthreadMutex;
//pthread_mutex_lock(&pthreadMutex);
//pthread_mutex_unlock(&pthreadMutex);
void *thread_tcp_recv(void *arg)
{
int struct_len = 0;
int numbytes = 0;
struct sockaddr_in client_addr;
char buff[BUFF_LEN] = { 0 };
struct_len = sizeof(struct sockaddr_in);
tcpsock_client_fd = accept(tcpsockfd, (struct sockaddr *)&client_addr, &struct_len);
printf("accept return: %d\n", tcpsock_client_fd);
printf("Get the Client~\n");
//numbytes = send(tcpsock_client_fd,"Welcome to my server\n",21,0);
while((numbytes = recv(tcpsock_client_fd, tcp_recvbuff, BUFSIZ, 0)) > 0)
{
tcp_recvbuff[numbytes] = '\0';
printf("TCP Recv[%d]:%s\n",numbytes,tcp_recvbuff);
if(strcmp(tcp_recvbuff,"tcplink") != 0 )
send(tcpsock_client_fd,tcp_recvbuff,numbytes,0);
}
close(tcpsock_client_fd);
//close(tcpsockfd);
}
void *thread_tcp_send(void *arg)
{
int numbytes = 0;
while(1){
if( strcmp(tcp_recvbuff,"tcplink") == 0 )
{
pthread_mutex_lock(&pthreadMutex);
printf("TCP thread_tcp_send Lock OK\n");
strcpy(tcp_recvbuff,"tcplinkkkkkkkkkkkkkkkkkkkk");
numbytes = strlen(tcp_recvbuff);
if( send(tcpsock_client_fd,tcp_recvbuff,numbytes,0) < 0 )
{
perror("TCP write send error");
}
//memset(tcp_recvbuff,0 ,sizeof(tcp_recvbuff));
pthread_mutex_unlock(&pthreadMutex);
printf("TCP thread_tcp_send unLock OKKKK\n");
}
}
}
int start_TCP_Service(int port)
{
int struct_len;
char buff[BUFF_LEN];
tcp_addr.sin_family = AF_INET;
tcp_addr.sin_port = htons(port);
tcp_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(tcp_addr.sin_zero), 8);
struct_len = sizeof(struct sockaddr_in);
tcpsockfd = socket(AF_INET, SOCK_STREAM, 0);
if( tcpsockfd < 0)
{
perror("tcpsockfd");
}
// 进行连接确认
while( bind(tcpsockfd, (struct sockaddr *)&tcp_addr, struct_len) == -1 );
printf("Tcp Bind Success!\n");
while( listen(tcpsockfd, 10) == -1 );
printf("Tcp Listening....\n");
printf("Tcp Ready for Accept,Waitting...\n");
//启动线程接收或者发送
pthread_t tcp_thread_send;
pthread_t tcp_thread_recv;
if( pthread_create(&tcp_thread_send, NULL, thread_tcp_send,NULL))
{
perror("TCP Create thead_updsend failed\n");//创建错误时执行
}
if( pthread_create(&tcp_thread_recv, NULL, thread_tcp_recv,NULL))
{
perror("TCP Create thead_udprecv failed\n");//创建错误时执行
}
return 0;
}
void *thead_updsend(void *arg)
{
#if 0
char buf[1024] = { 0 };
while(1)
{
udp_addr.sin_family = AF_INET;
udp_addr.sin_port = htons(udpport);
udp_addr.sin_addr.s_addr = htonl(INADDR_ANY);
//scanf("%s",buf);
memcpy(buf,"hello word",10);
if( strlen(buf) > 0)
{
pthread_mutex_lock(&pthreadMutex);
printf("UDP send buf=[%s] \n",buf);
sendto(udpsockfd,buf,strlen(buf),0,(struct sockaddr *)&udp_addr,sizeof(udp_addr));
memset(buf , 0 ,sizeof(buf));
pthread_mutex_unlock(&pthreadMutex);
}
sleep(1);
}
#endif
}
void *thead_udprecv(void *arg)
{
struct sockaddr_in client;
int rLen,len,PORT_INT = 0,count = 0;
char buff[BUFF_LEN] = {0};
char *IP_STR = NULL;
len = sizeof(client);
printf("UDP len=%d\n",len);
while(1){
rLen = recvfrom(udpsockfd,buff,BUFF_LEN,0,(struct sockaddr *)&client,&len);
IP_STR = (char *)inet_ntoa(client.sin_addr);
PORT_INT = ntohs(client.sin_port);
printf("UDP %d Received Address:%s:%d\n",count,IP_STR,PORT_INT);
printf("UDP %d Received Message[%d]:%s\n",count++,rLen,buff);
printf("\n");
sendto(udpsockfd,buff,rLen,0,(struct sockaddr *)&client,len);
memset(buff,0,BUFF_LEN);
}
}
int strt_UDP_Service(int port)
{
#if 1
int s = 0;
struct sockaddr_in addr_serv,addr_clie;
udpsockfd = socket(AF_INET,SOCK_DGRAM,0);
memset(&addr_serv,0,sizeof(addr_serv));
addr_serv.sin_family = AF_INET;
addr_serv.sin_addr.s_addr = htonl(INADDR_ANY);
addr_serv.sin_port = htons(port);
// struct timeval tv;
// tv.tv_sec = 1;
// tv.tv_usec = 0;//200000; // 200ms
// setsockopt(udpsockfd,SOL_SOCKET, SO_RCVTIMEO,(const char *)&tv,sizeof( struct timeval)); //设置超时
if( bind(udpsockfd,(struct sockaddr *)&addr_serv,sizeof(addr_serv)) )
{
printf("UDP failed to bind socket on port=%d\n",port);
close(udpsockfd);
return -1;
}
printf("UDP server create OK!\n");
int optVal;
int optLen = sizeof(int);
getsockopt(udpsockfd, SOL_SOCKET, SO_RCVBUF, (char*)&optVal, &optLen);
printf("The max length is %d\n", optVal);
pthread_t udp_thread_send;
pthread_t udp_thread_recv;
if( pthread_create(&udp_thread_send, NULL, thead_updsend,NULL))
{
perror("UDP Create thead_updsend failed\n");//创建错误时执行
}
if( pthread_create(&udp_thread_recv, NULL, thead_udprecv,NULL))
{
perror("UDP Create thead_udprecv failed\n");//创建错误时执行
}
#endif
return 0;
}
int main(int argc, char *argv[])
{
if(argc < 2)
{
printf("please input PORT just like %s 8889\n",argv[0]);
return 0;
}
udpport = atoi(argv[1]);
tcpport = atoi(argv[1]);
printf("udpport PORT = %d\n",udpport);
//初始化互斥锁
pthread_mutex_init(&pthreadMutex,NULL);
start_TCP_Service(tcpport);
strt_UDP_Service(udpport);
printf("main ...\n");
pthread_exit(NULL);//(1)结束主
printf("main stop...\n");
//销毁互斥锁
pthread_mutex_destroy(&pthreadMutex);
return 0;
}
编译命令为:
gcc tcp_udp_server.c -o tcp_udp -lpthread
TCP 客户端代码如下
tcp_client.c
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#define SERVER_PORT 8889
int main(int argc,char *argv[])
{
int sockfd,numbytes;
char buf[BUFSIZ];
struct sockaddr_in their_addr;
printf("break!");
//如果得到返回值不为0,说明socket没创建成功,继续等待,与服务端无关
while((sockfd = socket(AF_INET,SOCK_STREAM,0)) == -1);
printf("We get the sockfd~\n");
their_addr.sin_family = AF_INET;
their_addr.sin_port = htons(SERVER_PORT);
// 服务器 Socket 的 IP 地址
their_addr.sin_addr.s_addr=inet_addr("127.0.0.1");
bzero(&(their_addr.sin_zero), 8);
while(connect(sockfd,(struct sockaddr*)&their_addr,sizeof(struct sockaddr)) == -1);
printf("Get the Server OK~\n");
while(1)
{
printf("Enter something:");
scanf("%s\n",buf);
printf("scanf: %s\n", buf);
if( strlen(buf) > 0)
{
numbytes = send(sockfd, buf, strlen(buf), 0);
printf("send numbytes: %d\n", numbytes);
}
else{ continue; }
numbytes=recv(sockfd,buf,BUFSIZ,0);
printf("recv numbytes: %d\n", numbytes);
buf[numbytes]='\0';
printf("received:%s\n",buf);
memset(buf, 0 ,sizeof(buf));
}
close(sockfd);
return 0;
}
编译命令为
gcc tcp_client.c -o tcpclient
UDP 客户端代码如下
udp_client.c
//udp_client.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define PORT_SERV 8889
#define BUFF_LEN 1024
#define LINK_IP "127.0.0.1"
static void UDP_client(int udpsock,struct sockaddr_in *client)
{
int recvLen = 0;
char RecBuff[BUFF_LEN]="\n";
char SendBuff[BUFF_LEN] = {0};
int n;
struct sockaddr_in from;
int len = sizeof(*client);
printf("please input message!\n");
while(1){
n = read(0,SendBuff,BUFF_LEN);
SendBuff[n++] = '\0';
sendto(udpsock,SendBuff,n,0,(struct sockaddr *)client,len);
recvLen = recvfrom(udpsock,RecBuff,BUFF_LEN,0,(struct sockaddr*)&from,&len);
if( recvLen > 0 )
printf("recved[recvLen]:%s \n",RecBuff , recvLen);
}
}
int main(int argc,char **argv)
{
int udpsock;
struct sockaddr_in addr_serv,addr_clie;
char *msg;
/*
if(argc != 3){
printf("parameter is error!\n");
printf("format:ip port\n");
return -1;
}
*/
udpsock = socket(AF_INET,SOCK_DGRAM,0);
memset(&addr_clie,0,sizeof(addr_clie));
addr_clie.sin_family = AF_INET;
/*inet_addr(LINK_IP); inet_addr(argv[1])*/
addr_clie.sin_addr.s_addr = htonl(INADDR_ANY);
/*htons(atoi(argv[2]));*/
addr_clie.sin_port = htons(PORT_SERV);
UDP_client(udpsock,&addr_clie);
close(udpsock);
return 0;
}
编译命令如下
gcc udp_client.c -o udpclient
首先启动服务器
./tcp_udp 8889
然后分别执行
./tcp_client
./udp_client
可同时完成 UDP 和TCP的信息处理