创建一个TCP Server的连接需要以下几步:
一、服务器端
- socket:创建服务器监听套接字
- bind:绑定服务器监听信息到套接字上
- listen: 开始监听,接收客户端的TCP连接
- accept:从listen所维护的队列中取出一条已连接的TCP,返回该连接的socket描述字
- 服务器客户端在连接socket描述字上进行消息通信
- close:关闭打开着的套接字
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
#define C_DEFAULT_PORT 8008
#define C_BUFFER_SIZE 1024
void *recv_pthread(void * v_new_sock)
{
int sock = *(int *)v_new_sock;
char back_buf[C_BUFFER_SIZE];
char Child_buf[C_BUFFER_SIZE];
while (1)
{
memset(back_buf, '\0', C_BUFFER_SIZE);
memset(Child_buf, '\0', C_BUFFER_SIZE);
int get_size = recv(sock, Child_buf, sizeof(Child_buf), 0);
if (get_size == -1)
{
perror("recv失败");
}
else if (get_size == 0)
{
printf("用户sock=%d已下线,将退出子程序\n",sock);
return (void *)0;
}
else{
printf("收到来自sock=%d消息:%s\n",sock ,Child_buf);
strcat(back_buf,"服务器收到了\0");
strcat(back_buf,Child_buf);
send(sock, back_buf, sizeof(back_buf), 0);
}
}
}
int main()
{
int port = C_DEFAULT_PORT;
int C_sock = socket(PF_INET, SOCK_STREAM, 0);
if (C_sock == -1)
{
perror("Socket建立失败");
return 1;
}
else
printf("Socket建立成功\n");
struct sockaddr_in bind_addr;
memset(&bind_addr, 0, sizeof(bind_addr));
bind_addr.sin_family = AF_INET;
bind_addr.sin_addr.s_addr = htonl(INADDR_ANY);
bind_addr.sin_port = htons(port);
int C_bind = bind(C_sock, (struct sockaddr *)&bind_addr, sizeof(bind_addr));
if (C_bind == -1)
{
perror("bind建立失败");
return 1;
}
else
printf("bind建立成功\n");
int C_listen = listen(C_sock, 5);
if (C_listen == -1)
{
perror("listen建立失败");
return 1;
}
else
printf("listen建立成功\n");
while (1)
{
int new_sock = accept(C_sock, NULL, NULL);
if (new_sock == -1)
{
perror("new_sock建立失败");
return 1;
}
else
printf("\nnew_sock建立成功\n");
pthread_t s_thread,r_thread;
int r = pthread_create(&r_thread, NULL, recv_pthread, (void *)&new_sock);
if(r!=0)
perror("recv_pthread建立失败");
}
}
二、客户端
- socket:创建客户端连接套接字
- connect:向指定服务器发起连接请求
- 服务器客户端在连接socket描述字上进行消息通信
- close:关闭打开着的套接字
#include <netinet/in.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stdlib.h>
#include <pthread.h>
#define C_DEFAULT_PORT 8008
#define C_BUFFER_SIZE 1024
void *send_pthread(void * v_new_sock)
{
int sock = *(int *)v_new_sock;
char Child_buf[C_BUFFER_SIZE];
while (1)
{
memset(Child_buf, '\0', C_BUFFER_SIZE);
scanf("%s", Child_buf);
int send_size = send(sock, Child_buf, sizeof(Child_buf), 0);
if (send_size == -1)
{
perror("send失败");
}
}
}
void *recv_pthread(void * v_new_sock)
{
int sock = *(int *)v_new_sock;
char Child_buf[C_BUFFER_SIZE];
while (1)
{
memset(Child_buf, '\0', C_BUFFER_SIZE);
int get_size = recv(sock, Child_buf, sizeof(Child_buf), 0);
if (get_size == -1)
{
perror("recv失败");
}
else if (get_size == 0)
{
printf("对方已下线,将退出\n");
exit(1);
}
else
printf("收到消息:%s\n", Child_buf);
}
}
int main(void)
{
char ipstr[] = "127.0.0.1";
printf("请输入待连接的IP,输入0使用默认IP: ");
char T[100];
scanf("%s",T);
if(*(int *)T!=0)
strcpy(ipstr,T);
int C_sock = socket(AF_INET, SOCK_STREAM, 0);
if (C_sock == -1)
{
perror("Socket建立失败");
return 1;
}
else
printf("Socket建立成功\n");
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
inet_pton(AF_INET, ipstr, &server_addr.sin_addr.s_addr);
server_addr.sin_port = htons(C_DEFAULT_PORT);
int C_con = connect(C_sock, (struct sockaddr *)&server_addr, sizeof(server_addr));
if (C_con == -1)
{
perror("connect建立失败");
return 1;
}
else
printf("connect建立成功\n");
printf("\t可以开始聊天了:\n\n");
pthread_t s_thread,r_thread;
int s = pthread_create(&s_thread, NULL, send_pthread, (void *)&C_sock);
if (s !=0)
perror("send_pthread建立失败");
int r = pthread_create(&r_thread, NULL, recv_pthread, (void *)&C_sock);
if (r !=0)
perror("recv_pthread建立失败");
pthread_join(s_thread,NULL);
pthread_join(r_thread,NULL);
close(C_sock);
return 0;
}