外网做socket通信--问题
各位高手,我在外网做一个socket通信程序,现在遇到这样的问题,请教一下:
client端发送一个文件数据的时候,小一点的没问题,大一点的比如8k,server端读了2-3个1024字节之后就会阻塞,client端发送了10个左右的1024字节之后也会阻塞,有高手指点一下吗?
程序在局域网内测试都是没问题的。但是一放到外网来,就这样。
程序还有一些没贴出来的,都是变量的定义。
client:
memset(&ser_addr, 0, sizeof(ser_addr));
memset(&host_addr, 0, sizeof(host_addr));
ser_addr.sin_family = AF_INET;
inet_aton(REMOTE_IP, (struct in_addr *)&ser_addr.sin_addr);
ser_addr.sin_port = htons(SERVER_PORT);
sock_fd = socket(AF_INET, SOCK_STREAM, 0);
if (sock_fd < 0)
{
printf("%s, %d, create socket failed\n", __FILE__, __LINE__);
exit(1);
}
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, (char *)&brecord_flag, sizeof(brecord_flag));
setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, (char *)&brecord_flag, sizeof(brecord_flag));
bind(sock_fd, (struct sockaddr *)&host_addr, sizeof(host_addr));
if (connect(sock_fd, (struct sockaddr *)&ser_addr, sizeof(ser_addr)) < 0)
{
printf("%s, %d, connect socket failed\n", __FILE__, __LINE__);
exit(1);
}
if ((from_fd = open(argv[1], O_RDONLY)) == -1)
{
fprintf(stderr, "Open %s Error: %s\n", argv[1], strerror(errno));
exit(1);
}
filesize = get_file_size(argv[1]);
if (filesize <= 0)
exit(1);
left_size = filesize;
while(left_size > 0)
{
bytes_read = read(from_fd, buffer, BUFFER_SIZE);
if (bytes_read <= 0)
{
printf("read end!\n");
close(from_fd);
break;
}
sendlen = bytes_read;
retlen = send(sock_fd, buffer, sendlen, 0);
printf("retlen = %d\n", retlen);
if (retlen < 0)
{
if (errno == EINTR)
{
retlen = 0;
printf("continue wait for send!\n");
}
else
{
printf("error to send %s\n", strerror(errno));
printf("recreate sock\n");
close(sock_fd);
close(from_fd);
goto L1;
}
}
left_size -= retlen;
}
return 0;
server:
void *rcvData(void *arg)
{
int cnfd = *((int *)arg);
char recvbuf[RECV_BUF_SIZE] = {0};
int bytes_write;
int retlen = 0;
char fileName[MAX_FILE_NAME_LEN];
int to_fd;
char BindFileName[MAX_FILE_NAME_LEN];
sprintf(fileName, "store_file_%d.ts", pthread_count);
strcpy(BindFileName, fileName);
// if ((to_fd = open(fileName, O_RDWR | O_CREAT, 0777)) == -1)
// {
// printf("Open %s Error: %s\n", fileName, strerror(errno));
// exit(1);
// }
#if 0
if(fcntl(cnfd, F_SETFL, O_NONBLOCK) == -1) {
printf("error to set NONBLOCK!\n");
exit(1);
}
#endif
while (1)
{
pthread_mutex_lock(&mutex);
//pthread_cond_wait(&cond, &mutex);
printf("recv onece __line %d\n", __LINE__);
memset(recvbuf, 0, sizeof(recvbuf));
//retlen = recv(cnfd, recvbuf, RECV_BUF_SIZE, 0);
retlen = recv(cnfd, recvbuf, RECV_BUF_SIZE, MSG_NOSIGNAL);
printf("retlen = %d\n", retlen);
if(retlen < 0)
{
if (errno == EINTR || errno == EAGAIN)
{
pthread_mutex_unlock(&mutex);
continue;
}
printf("recv Error: %s\n", strerror(errno));
break;
}
else if (retlen == 0)
{
printf("recv end!\n");
pthread_mutex_unlock(&mutex);
break;
}
printf("recv onece __line %d\n", __LINE__);
if ((to_fd = open(BindFileName, O_RDWR | O_CREAT | O_APPEND, 0777)) == -1)
{
printf("Open %s Error: %s\n", fileName, strerror(errno));
exit(1);
}
bytes_write = write(to_fd, recvbuf, retlen);
if (bytes_write != retlen)
{
printf("write file error!\n");
break;
}
printf("recv onece __line %d\n", __LINE__);
close(to_fd);
pthread_mutex_unlock(&mutex);
}
pthread_mutex_unlock(&mutex);
close(cnfd);
pthread_exit(NULL);
}
int main
{
...
pthread_mutex_init(&mutex, NULL);
//pthread_cond_init(&cond, NULL);
memset((void *)&hostaddr, 0, sizeof(hostaddr));
memset((void *)&clientaddr, 0, sizeof(clientaddr));
hostaddr.sin_family = AF_INET;
hostaddr.sin_port = htons(LISTEN_PORT);
hostaddr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_sock = socket(AF_INET, SOCK_STREAM, 0);
if(listen_sock < 0)
{
printf("%s, %d, create socket failed\n", __FILE__, __LINE__);
exit(1);
}
if(bind(listen_sock, (struct sockaddr *)&hostaddr, sizeof(hostaddr)) < 0)
{
printf("%s, %d, bind socket failed\n", __FILE__, __LINE__);
exit(1);
}
//if(listen(listen_sock, MAX_LISTEN_NUM) < 0)
if(listen(listen_sock, SOMAXCONN) < 0)//128
{
printf("%s, %d, listen failed\n", __FILE__, __LINE__);
exit(1);
}
while(1)
{
app_sock = accept(listen_sock, (struct sockaddr *)&clientaddr, &socklen);
if(app_sock < 0)
{
printf("%s:%d, accept failed", __FILE__, __LINE__);
exit(1);
}
else
{
printf("There is a new socket link coming %d!\n", app_sock);
if (pthread_create(&tid, NULL, rcvData, &app_sock))
{
perror("rcv pthread_create\n");
}
pthread_count += 1;
}
}
}